﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;


namespace MetaDemo
{
    class Program
    {

        public static string program_path = null;
        static string[] program_args = null;


        [STAThreadAttribute]
        static void Main(string[] args)
        {
            ParseCommandLineArguments(args);

            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");

            StartStatically();
        }

        static void PrintUsage()
        {
            Console.WriteLine("Usage: MetaDemo ASSEMBLY_PATH [ARG...]");
            Console.WriteLine();
            Console.WriteLine("ASSEMBLY_PATH  Where to find the executable to load, start and instrument.");
            Console.WriteLine("ARG            Arguments for the instrumented executable.");
        }

        static void ParseCommandLineArguments(string[] args)
        {
            if (0 == args.Count())
            {
                PrintUsage();
                Environment.Exit(1);
            }

            program_path = Path.GetFullPath(args[0]);
            Console.WriteLine(program_path);

            if (1 == args.Count())
            {
                program_args = new string[] { };
            }
            else
            {
                program_args = new string[args.Count()-1];
                Array.Copy(args, 1, program_args, 0, args.Count() - 1);
            }
        }

        static void StartStatically()
        {
            var assembly = Assembly.LoadFrom(program_path);

            KeyHandling.RegisterGlobalKeyEventHandler();

            if (assembly.EntryPoint == null)
            {
                PrintUsage();
                Environment.Exit(1);
            }
            else if (assembly.EntryPoint.GetParameters().Length == 0)
            {
                assembly.EntryPoint.Invoke(null, null);
            }
            else
            {
                assembly.EntryPoint.Invoke(null, new Object[] { program_args });
            }
        }

    }


}
